/**
 * Serponix is an arcade game in focus to multiplayer based on the classic game
 * Snake. Copyright (C) 2010 - 2011 Daniel Vala
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * If you have any question do not hesitate to contact author on e-mail address:
 * danielvala42@gmail.com
 */
package com.serponix.gui.settings;

import com.serponix.gui.MainPanel;
import com.serponix.settings.GameSettings;
import com.serponix.settings.SnakeAction;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.util.Observable;
import java.util.Observer;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;

/**
 * View obsahuje všechny komponenty GUI pro zobrazení nastavení kláves, jmen
 * hráčů, počtu hráčů, čísla portu a tlačítek pro uložení, storno a default.
 *
 * @author Daniel Vala
 */
public class ViewNastaveni extends JPanel implements Observer {

	private final int POCET_HRACU = 4;
	private ModelNastaveni model;
	private JPanel panel;
	private JButton[][] buttony;
	private JTextField[] textFieldsJmena;
	private JSpinner spinnerPocetHracu, spinnerPort;
	private SnakeAction[] klavesy = { SnakeAction.UP, SnakeAction.DOWN, SnakeAction.LEFT, SnakeAction.RIGHT, SnakeAction.FIRE, SnakeAction.FIRE2 };
	private JButton ulozitButton, vychoziButton, stornoButton;

	public ViewNastaveni(ModelNastaveni model, MainPanel okno) {
		this.model = model;
		GameSettings gameSettings = GameSettings.getInstance();
		buttony = new JButton[POCET_HRACU][6];
		panel = new JPanel(new BorderLayout(30, 30));

		JPanel panelVsechOvladani = new JPanel(new GridLayout(4, 1, 0, 50));
		textFieldsJmena = new JTextField[POCET_HRACU];
		for (int i = 0; i < POCET_HRACU; i++) {
			panelVsechOvladani.add(vytvorPanelOvladani(i));
		}
		panel.add(panelVsechOvladani, BorderLayout.NORTH);

		JPanel panelDalsihoNastaveni = new JPanel();

		panelDalsihoNastaveni.add(new JLabel("počet hráčů"));

		spinnerPocetHracu = new JSpinner(new SpinnerNumberModel(2, 1, 4, 1));
		spinnerPocetHracu.setValue(gameSettings.getNumberOfActivePlayers());
		spinnerPocetHracu.addChangeListener(new SetPocetHracuController(this));
		panelDalsihoNastaveni.add(spinnerPocetHracu);

		panelDalsihoNastaveni.add(new JLabel("port"));
		spinnerPort = new JSpinner(new SpinnerNumberModel(gameSettings.getPort(), 1, 65535, 1));
		panelDalsihoNastaveni.add(spinnerPort);

		JButton napovedaPort = new JButton("?");
		napovedaPort.addActionListener(new ControllerNapovedaPort(this));
		panelDalsihoNastaveni.add(napovedaPort);

		panel.add(panelDalsihoNastaveni, BorderLayout.CENTER);

		JPanel panelPotvrzeni = new JPanel();
		vychoziButton = new JButton("Výchozí");
		vychoziButton.addActionListener(new SetDefaultController(model));
		panelPotvrzeni.add(vychoziButton);

		ulozitButton = new JButton("Uložit");
		ulozitButton.addActionListener(new ControllerSave(model, this, okno));
		panelPotvrzeni.add(ulozitButton);

		stornoButton = new JButton("Storno");
		stornoButton.addActionListener(new MenuController(okno));
		panelPotvrzeni.add(stornoButton);

		panel.add(panelPotvrzeni, BorderLayout.SOUTH);

		add(panel);

		setPocetEditovatelnychJmen(gameSettings.getNumberOfActivePlayers());
		model.addObserver(this);
	}

	/**
	 * Nastaví editovatelné jména a tlačítka pro nastavení kláves zadanému počtu
	 * hráčů.
	 *
	 * @param pocet Pocet hráčů, kteří si budou moci nastavit své ovládání.
	 */
	public void setPocetEditovatelnychJmen(int pocet) {
		if (pocet < 1 || pocet > POCET_HRACU) {
			return;
		}
		for (int i = 0; i < pocet; i++) {
			textFieldsJmena[i].setEnabled(true);
			for (int j = 0; j < 6; j++) {
				buttony[i][j].setEnabled(true);
			}
		}
		for (int i = pocet; i < 4; i++) {
			textFieldsJmena[i].setEnabled(false);
			for (int j = 0; j < 6; j++) {
				buttony[i][j].setEnabled(false);
			}
		}
	}

	public String getTextFieldJmeno(int i) {
		return textFieldsJmena[i].getText();
	}

	public int getPocetHracu() {
		return (Integer) spinnerPocetHracu.getValue();
	}

	public int getPort() {
		return (Integer) spinnerPort.getValue();
	}

	private JPanel vytvorPanelOvladani(int hrac) {
		JPanel panelKlaves = new JPanel(new GridLayout(2, 8));

		textFieldsJmena[hrac] = new JTextField(GameSettings.getInstance().getNameOfGivenPlayer(hrac), 7);

		for (int i = 0; i < klavesy.length; i++) {
			buttony[hrac][i] = new MyButton(KeyEvent.getKeyText(model.getKeyOfGivenPlayer(hrac).get(klavesy[i])));
			buttony[hrac][i].addKeyListener(new KeyController(model, buttony[hrac][i], hrac, klavesy[i]));
		}

		panelKlaves.add(new JPanel());
		panelKlaves.add(new JPanel());
		panelKlaves.add(new JPanel());
		panelKlaves.add(buttony[hrac][0]);
		panelKlaves.add(new JPanel());
		panelKlaves.add(new JPanel());
		panelKlaves.add(buttony[hrac][4]);
		panelKlaves.add(new JLabel("laser"));

		// nový řádek
		panelKlaves.add(textFieldsJmena[hrac]);
		panelKlaves.add(new JPanel());
		panelKlaves.add(buttony[hrac][2]);
		panelKlaves.add(buttony[hrac][1]);
		panelKlaves.add(buttony[hrac][3]);
		panelKlaves.add(new JPanel());
		panelKlaves.add(buttony[hrac][5]);
		panelKlaves.add(new JLabel("raketa"));

		return panelKlaves;
	}

	@Override
	public void update(Observable o, Object arg) {
		GameSettings gameSettings = GameSettings.getInstance();
		for (int j = 0; j < buttony.length; j++) {
			for (int i = 0; i < buttony[j].length; i++) {
				buttony[j][i].setText(KeyEvent.getKeyText(model.getKeyOfGivenPlayer(j).get(klavesy[i])));
			}
		}
		for (int i = 0; i < textFieldsJmena.length; i++) {
			textFieldsJmena[i].setText(gameSettings.getNameOfGivenPlayer(i));
		}
		setPocetEditovatelnychJmen(gameSettings.getNumberOfActivePlayers());
		spinnerPocetHracu.setValue(gameSettings.getNumberOfActivePlayers());
		spinnerPort.setValue(gameSettings.getPort());
	}

	/**
	 * Třída mění velikost standardního tlačítka na šířku 100.
	 */
	private static class MyButton extends JButton {

		public MyButton(String text, Icon icon) {
			super(text, icon);
		}

		public MyButton(Action a) {
			super(a);
		}

		public MyButton(String text) {
			super(text);
		}

		public MyButton(Icon icon) {
			super(icon);
		}

		public MyButton() {
		}

		@Override
		public Dimension getPreferredSize() {
			Dimension d = super.getPreferredSize();
			d.width = 100;
			return d;
		}
	}
}
